| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- 'use client';
- import { useState, useRef, useEffect, useCallback } from 'react';
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
- import { faShare, faLink, faCheck } from '@fortawesome/free-solid-svg-icons';
- import { faFacebook, faXTwitter } from '@fortawesome/free-brands-svg-icons';
- import './share-menu.scss';
- type Props = {
- title: string;
- };
- export default function ShareMenu({ title }: Props) {
- const [open, setOpen] = useState(false);
- const [copied, setCopied] = useState(false);
- const wrapperRef = useRef<HTMLDivElement>(null);
- useEffect(() => {
- if (!open) {
- return;
- }
- const handler = (e: MouseEvent) => {
- if (wrapperRef.current && !wrapperRef.current.contains(e.target as Node)) {
- setOpen(false);
- }
- };
- document.addEventListener('mousedown', handler);
- return () => document.removeEventListener('mousedown', handler);
- }, [open]);
- const openShare = useCallback((target: string) => {
- const current = typeof window !== 'undefined' ? window.location.href : '';
- const url = encodeURIComponent(current);
- const text = encodeURIComponent(title);
- let shareUrl = '';
- switch (target) {
- case 'facebook':
- shareUrl = `https://www.facebook.com/sharer/sharer.php?u=${url}`;
- break;
- case 'twitter':
- shareUrl = `https://twitter.com/intent/tweet?url=${url}&text=${text}`;
- break;
- case 'band':
- shareUrl = `https://band.us/plugin/share?body=${text}%20${url}`;
- break;
- default:
- return;
- }
- const width = 600;
- const height = 500;
- const left = window.screenX + (window.outerWidth - width) / 2;
- const top = window.screenY + (window.outerHeight - height) / 2;
- window.open(shareUrl, '_blank', `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`);
- setOpen(false);
- }, [title]);
- const copyLink = useCallback(async () => {
- try {
- await navigator.clipboard.writeText(window.location.href);
- setCopied(true);
- window.setTimeout(() => {
- setCopied(false);
- setOpen(false);
- }, 1200);
- } catch {
- setCopied(false);
- }
- }, []);
- return (
- <div className='share-menu' ref={wrapperRef}>
- <button
- type='button'
- className='share-menu__trigger'
- onClick={() => setOpen((prev) => !prev)}
- aria-haspopup='menu'
- aria-expanded={open}
- >
- <FontAwesomeIcon icon={faShare} />
- <span>공유</span>
- </button>
- {open && (
- <div className='share-menu__dropdown' role='menu'>
- <button type='button' onClick={copyLink} role='menuitem'>
- <FontAwesomeIcon icon={copied ? faCheck : faLink} />
- <span>{copied ? '링크가 복사되었습니다' : '링크 복사'}</span>
- </button>
- <button type='button' onClick={() => openShare('twitter')} role='menuitem'>
- <FontAwesomeIcon icon={faXTwitter} />
- <span>X (Twitter)</span>
- </button>
- <button type='button' onClick={() => openShare('facebook')} role='menuitem'>
- <FontAwesomeIcon icon={faFacebook} />
- <span>Facebook</span>
- </button>
- <button type='button' onClick={() => openShare('band')} role='menuitem'>
- <span aria-hidden='true' className='share-menu__band'>B</span>
- <span>Band</span>
- </button>
- </div>
- )}
- </div>
- );
- }
|